﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.Serialization;
using System.Security.Permissions;

namespace SpeakupBackend.Themes
{
    [Serializable]
    public class LevelGroup : IEquatable<LevelGroup>, 
                                     IComparable, 
                                     IComparable<LevelGroup>
                                     
    {
        static public readonly DefaultLevelGroupFactory DefaultFactory = new DefaultLevelGroupFactory();
        static public readonly char LevelSplitter = '-';

        readonly int m_minLevel;
        readonly int m_maxLevel;
        
        public int MinLevel
        {
            get
            {
                return m_minLevel;
            }
        }
        public int MaxLevel
        {
            get
            {
                return m_maxLevel;
            }
        }

        internal protected LevelGroup(int minLevel, int maxLevel)
        {
            if (!Level.IsValidLevelNumber(minLevel))
            {
                throw new ArgumentException("minLevel");
            }

            if(!Level.IsValidLevelNumber(maxLevel))
            {
                throw new ArgumentException("maxLevel");
            }

            if (maxLevel < minLevel)
            {
                throw new ArgumentException("maxLevel < minLevel");
            }

            m_minLevel = minLevel;
            m_maxLevel = maxLevel;
        }

        public bool ContainsLevel(Level level)
        {
            return MinLevel <= level.LevelNumber && level.LevelNumber <= MaxLevel;
        }

        public IList<Level> GetLevels()
        {
            List<Level> levels = new List<Level>();
            for (int i = MinLevel; i <= MaxLevel; i++)
            {
                levels.Add(Level.GetLevel(i));
            }

            return levels;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as LevelGroup);
        }

        public bool Equals(LevelGroup other)
        {
            return ClassHelper.IEquatableEquals(this, other);
        }

        public override int GetHashCode()
        {
            return ClassHelper.GetHashCode(MinLevel, MaxLevel); 
        }

        public override string ToString()
        {
            if(MinLevel == MaxLevel)
            {
                return String.Format("{0}",MinLevel);
            }
            else
            {
                return String.Format("{0}{1}{2}",MinLevel, LevelSplitter, MaxLevel);
            }
        }

        public int CompareTo(Object obj)
        {
            return CompareTo((LevelGroup)obj);
        }

        public int CompareTo(LevelGroup lvlGroup)
        {
            if (lvlGroup.MinLevel == MinLevel &&
                lvlGroup.MaxLevel == MaxLevel)
            {
                return 0;
            }
            return MinLevel - lvlGroup.MinLevel;
        }


        #region Comparison operators 

        public static bool operator ==(LevelGroup rhs, LevelGroup lhs)
        {
            return ClassHelper.OperatorEqual(rhs, lhs);
        }

        public static bool operator !=(LevelGroup rhs, LevelGroup lhs)
        {
            return ClassHelper.OperatorNotEqual(rhs, lhs);
        }

        public static bool operator <(LevelGroup rhs, LevelGroup lhs)
        {
            return rhs.CompareTo(lhs) < 0;
        }

        public static bool operator > (LevelGroup rhs, LevelGroup lhs)
        {
            return rhs.CompareTo(lhs) > 0;
        }

        public static bool operator <=(LevelGroup rhs, LevelGroup lhs)
        {
            return rhs.CompareTo(lhs) <= 0;
        }

        public static bool operator >=(LevelGroup rhs, LevelGroup lhs)
        {
            return rhs.CompareTo(lhs) >= 0;
        }

        #endregion
    }
}
